local runtime = require 'jass.runtime'

ac.triggercount = 0

local actor_class = {
    
    __call = function(self, trigger, func)
        local atcor = setmetatable({
            name = trigger.name,
            trigger = trigger,
            func = func,
            enable_flag = true,
        }, self)
        ac.triggercount = ac.triggercount + 1 
        return atcor
    end,

    __tostring = function(self)
        return ('[触发器] @%q #(line:%d)'):format(self._src or 'nil', self._line or 'nil')
    end,

    __index = {

        enable = function(self)
            self.enable_flag = true
        end,

        disable = function(self)
            self.enable_flag = false
        end,

        is_enable = function(self)
            return self.enable_flag
        end,

        execute = function(self, ...)
            if self.removed then return end 
            if self.func and self.enable_flag then 
                return select(2, xpcall(self.func, runtime.error_handle, self, ...) )
            end 
        end,

        remove = function(self)
            if self.removed then return end 
            self.removed = true
            ac.triggercount = ac.triggercount - 1
            ac.wait(0, function()
                if not self.trigger then return end
                for i, t in ipairs(self.trigger.actors) do
                    if t == self then
                        table.remove(self.trigger.actors, i)
                        break
                    end
                end
            end)
        end,
    },
}

setmetatable(actor_class, actor_class)

local trigger = {}
setmetatable(trigger, trigger)
ac.trigger = trigger

--[创建]
function trigger.create(name)
    local t = {}
    t.name = name 
    t.actors = {}
    setmetatable(t, trigger)
    return t
end 

local mt = {}
trigger.__index = mt

---类型
mt.type = 'trigger'

--[添加]
function mt:add_actor(func)
    local actor = actor_class(self, func)
    if package.local_test then 
        local info = debug.getinfo(3, "Sl")
        if info then 
            actor._src = info.short_src
            actor._line = info.currentline
        end
    end
    table.insert(self.actors, actor)
    return actor
end 

--[notify]
function mt:notify(...)
    if self.removed then return end
    for i = #self.actors, 1, -1 do 
        self.actors[i]:execute(...)
    end 
end

--[dispatch]
function mt:dispatch(...)
    if self.removed then return end
    for i = #self.actors, 1, -1 do 
        local bool, resion = self.actors[i]:execute(...)
        if bool ~= nil then 
            return bool, resion 
        end 
    end 
end
    
return trigger